package cc.sunni.activiti.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author jl
 * @since 2021/1/27 20:50
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private LoginSuccessHandler loginSuccessHandler;
    @Autowired
    private LoginFailureHandler loginFailureHandler;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 放行的资源配置
     * web.ignoring() 用来配置忽略掉的 URL 地址，一般对于静态文件，我们可以采用此操作。
     * 这里的请求不会经过的 Spring Security 过滤器链
     */
    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/layuimini/lib/**", "/layuimini/css/**", "/layuimini/js/**", "/css/**", "/js/**", "/index.html", "/img/**", "/fonts/**", "/favicon.ico", "/verifyCode", "/vc.jpg");
    }

    /**
     * 配置登录项
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 设置静态的资源允许所有访问
                .antMatchers("/static/**", "/bpmn*/**").permitAll()
                // 放行swagger
                .antMatchers("/swagger**/**", "/webjars/**", "/v3/**").anonymous()
                // 对于登录login 验证码captchaImage 允许匿名访问
                .antMatchers("/layuimini/page/login-1.html", "/layuimini/images/captcha.jpg").anonymous()
                // 其他所有资源都需要认证(登陆)后才能访问
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login") // 当我们定义了登录页面为 /login 且没有定义登录接口地址的时候，Spring Security 会帮我们自动注册一个 /login 的接口，这个接口是 POST 请求，用来处理登录逻辑。
                .successHandler(loginSuccessHandler)
                .failureHandler(loginFailureHandler)
                .defaultSuccessUrl("/layuimini/index.html")
                .and()
                .logout().permitAll()
                .and()
                .csrf().disable()
                // 防止iframe嵌入网页被拦截
                .headers().frameOptions().disable();
        // AuthenticationEntryPoint 用来解决匿名用户访问无权限资源时的异常
        http.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint())
                // accessDeniedHandler 用来解决认证过的用户访问无权限资源时的异常. 比如需要admin角色等
                .accessDeniedHandler(new CustomAccessDeniedHandler());
    }


}
